import { DIContainer } from '../../infrastructure/di';
import { 
    IGameService, 
    ServiceStatus, 
    HealthCheckResult, 
    ServiceMetrics, 
    ServiceLifecycle,
    ServiceEventType,
    ServiceEvent,
    ServiceConfig
} from './IGameService';

/**
 * 游戏服务基础实现类
 * 提供统一的服务管理功能，所有现代化服务都应该继承此类
 */
export abstract class BaseGameService implements IGameService {
    /** 服务名称 - 子类必须实现 */
    abstract readonly serviceName: string;
    
    /** 服务版本 */
    readonly version: string = '3.0.0';
    
    /** 当前生命周期状态 */
    protected _lifecycle: ServiceLifecycle = ServiceLifecycle.CREATED;
    get lifecycle(): ServiceLifecycle { return this._lifecycle; }
    
    /** 服务依赖列表 - 子类可以重写 */
    readonly dependencies: string[] = [];
    
    /** DI容器引用 */
    protected container?: DIContainer;
    
    /** 服务配置 */
    protected config: ServiceConfig = {};
    
    /** 性能指标 */
    private metrics: ServiceMetrics = {
        callCount: 0,
        avgResponseTime: 0,
        errorRate: 0
    };
    
    /** 错误计数 */
    private errorCount: number = 0;
    
    /** 初始化时间戳 */
    private initTimestamp: number = 0;
    
    /** 最后心跳时间 */
    private lastHeartbeat: number = Date.now();
    
    /** 健康检查定时器 */
    private healthCheckTimer?: NodeJS.Timeout;

    constructor(container?: DIContainer, config?: ServiceConfig) {
        this.container = container;
        this.config = { 
            enabled: true,
            timeout: 30000,
            maxRetries: 3,
            healthCheckInterval: 60000,
            ...config 
        };
        
        this.log('info', 'Service instance created');
    }

    /**
     * 初始化服务
     */
    async init(): Promise<void> {
        if (this._lifecycle !== ServiceLifecycle.CREATED) {
            this.log('warn', `Service already initialized, current state: ${this._lifecycle}`);
            return;
        }

        this._lifecycle = ServiceLifecycle.INITIALIZING;
        this.initTimestamp = Date.now();
        
        try {
            this.log('info', 'Initializing service...');
            
            // 检查依赖服务
            await this.checkDependencies();
            
            // 执行子类初始化逻辑
            await this.onInit();
            
            // 启动健康检查
            this.startHealthCheck();
            
            this._lifecycle = ServiceLifecycle.READY;
            this.log('info', 'Service initialized successfully');
            
            // 发送初始化事件
            this.emitEvent(ServiceEventType.INITIALIZED, { initTime: Date.now() - this.initTimestamp });
            
        } catch (error) {
            this._lifecycle = ServiceLifecycle.ERROR;
            this.recordError(error as Error);
            this.log('error', `Service initialization failed: ${(error as Error).message}`);
            throw error;
        }
    }

    /**
     * 销毁服务
     */
    async destroy(): Promise<void> {
        this._lifecycle = ServiceLifecycle.DESTROYING;
        
        try {
            this.log('info', 'Destroying service...');
            
            // 停止健康检查
            if (this.healthCheckTimer) {
                clearInterval(this.healthCheckTimer);
                this.healthCheckTimer = undefined;
            }
            
            // 执行子类销毁逻辑
            await this.onDestroy();
            
            this._lifecycle = ServiceLifecycle.DESTROYED;
            this.log('info', 'Service destroyed successfully');
            
        } catch (error) {
            this.log('error', `Service destruction failed: ${(error as Error).message}`);
            throw error;
        }
    }

    /**
     * 获取服务状态
     */
    getStatus(): ServiceStatus {
        return {
            serviceName: this.serviceName,
            version: this.version,
            isInitialized: this._lifecycle === ServiceLifecycle.READY,
            isHealthy: this._lifecycle === ServiceLifecycle.READY && this.errorCount < 10,
            lastHeartbeat: this.lastHeartbeat,
            errorCount: this.errorCount,
            dependencies: this.dependencies
        };
    }

    /**
     * 健康检查
     */
    async healthCheck(): Promise<HealthCheckResult> {
        const startTime = Date.now();
        
        try {
            // 更新心跳时间
            this.lastHeartbeat = Date.now();
            
            // 基础健康检查
            if (this._lifecycle !== ServiceLifecycle.READY) {
                return {
                    healthy: false,
                    message: `Service not ready, current state: ${this._lifecycle}`,
                    timestamp: Date.now()
                };
            }
            
            // 检查错误率
            if (this.metrics.errorRate > 0.1) { // 错误率超过10%
                return {
                    healthy: false,
                    message: `High error rate: ${(this.metrics.errorRate * 100).toFixed(2)}%`,
                    timestamp: Date.now()
                };
            }
            
            // 执行子类健康检查
            const customResult = await this.onHealthCheck();
            
            const responseTime = Date.now() - startTime;
            return {
                healthy: customResult.healthy,
                message: customResult.message,
                timestamp: Date.now(),
                details: {
                    ...customResult.details,
                    responseTime,
                    errorCount: this.errorCount,
                    metrics: this.metrics
                }
            };
            
        } catch (error) {
            this.recordError(error as Error);
            return {
                healthy: false,
                message: `Health check failed: ${(error as Error).message}`,
                timestamp: Date.now()
            };
        }
    }

    /**
     * 获取性能指标
     */
    getMetrics(): ServiceMetrics {
        return { ...this.metrics };
    }

    /**
     * 记录方法调用（用于性能监控）
     */
    protected async recordCall<T>(methodName: string, operation: () => Promise<T>): Promise<T> {
        const startTime = Date.now();
        this.metrics.callCount++;
        
        try {
            const result = await operation();
            
            // 更新平均响应时间
            const responseTime = Date.now() - startTime;
            this.metrics.avgResponseTime = 
                (this.metrics.avgResponseTime * (this.metrics.callCount - 1) + responseTime) / this.metrics.callCount;
            
            return result;
            
        } catch (error) {
            this.recordError(error as Error);
            throw error;
        }
    }

    /**
     * 记录错误
     */
    protected recordError(error: Error): void {
        this.errorCount++;
        this.metrics.errorRate = this.errorCount / Math.max(this.metrics.callCount, 1);
        this.metrics.lastError = {
            message: error.message,
            timestamp: Date.now(),
            stack: error.stack
        };
        
        this.emitEvent(ServiceEventType.ERROR, {
            error: error.message,
            stack: error.stack
        });
    }

    /**
     * 获取依赖服务
     */
    protected getService<T>(serviceName: string): T {
        if (!this.container) {
            throw new Error(`Cannot get service ${serviceName}: DI container not available`);
        }
        
        try {
            return this.container.resolve<T>(serviceName);
        } catch (error) {
            this.log('error', `Failed to resolve service ${serviceName}: ${(error as Error).message}`);
            throw new Error(`Dependency ${serviceName} not available`);
        }
    }

    /**
     * 日志记录
     */
    protected log(level: 'info' | 'warn' | 'error', message: string, data?: any): void {
        const timestamp = new Date().toISOString();
        const logMessage = `[${timestamp}] [${this.serviceName}] [${level.toUpperCase()}] ${message}`;
        
        if (data) {
            console.log(logMessage, data);
        } else {
            console.log(logMessage);
        }
    }

    /**
     * 发送服务事件
     */
    protected emitEvent(type: ServiceEventType, data: any): void {
        const event: ServiceEvent = {
            type,
            serviceName: this.serviceName,
            timestamp: Date.now(),
            data
        };
        
        // 这里可以集成到全局事件系统
        this.log('info', `Service event: ${type}`, event);
    }

    // ==================== 抽象方法 - 子类必须实现 ====================

    /**
     * 子类初始化逻辑
     */
    protected abstract onInit(): Promise<void>;

    /**
     * 子类销毁逻辑
     */
    protected abstract onDestroy(): Promise<void>;

    /**
     * 子类健康检查逻辑
     */
    protected abstract onHealthCheck(): Promise<HealthCheckResult>;

    // ==================== 私有方法 ====================

    /**
     * 检查依赖服务
     */
    private async checkDependencies(): Promise<void> {
        if (!this.container || this.dependencies.length === 0) {
            return;
        }
        
        for (const dependency of this.dependencies) {
            try {
                const service = this.container.resolve(dependency);
                if (!service) {
                    throw new Error(`Dependency ${dependency} not available`);
                }
                
                // 如果依赖也是IGameService，检查其状态
                if (typeof (service as any).getStatus === 'function') {
                    const status = (service as IGameService).getStatus();
                    if (!status.isHealthy) {
                        throw new Error(`Dependency ${dependency} is not healthy`);
                    }
                }
                
            } catch (error) {
                this.emitEvent(ServiceEventType.DEPENDENCY_FAILED, { dependency, error: (error as Error).message });
                throw new Error(`Dependency check failed for ${dependency}: ${(error as Error).message}`);
            }
        }
        
        this.log('info', `All dependencies checked: ${this.dependencies.join(', ')}`);
    }

    /**
     * 启动健康检查定时器
     */
    private startHealthCheck(): void {
        if (!this.config.healthCheckInterval || this.config.healthCheckInterval <= 0) {
            return;
        }
        
        this.healthCheckTimer = setInterval(async () => {
            try {
                const result = await this.healthCheck();
                if (!result.healthy) {
                    this.emitEvent(ServiceEventType.HEALTH_CHECK_FAILED, result);
                    this.log('warn', `Health check failed: ${result.message}`);
                }
            } catch (error) {
                this.log('error', `Health check error: ${(error as Error).message}`);
            }
        }, this.config.healthCheckInterval);
    }
}
